#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##---------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh
## Copyright (C) 2010-2013 Jeremy Austin-Bardo
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##---------------------------------------------------------------------------##

from ... import autostacks
from ... import pilelib as stack
from ...formlib import Layout
from ...gamelib import info as gi, game
from ...hint import CautiousDefaultHint
from ...packlib import place

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper

class TowerOfHanoy_RowStack(stack.BasicRowStack):
    _BOTTOM_IMAGE = 'shade'

    def cardsBuild(self, from_stack, cards):
        if not super(TowerOfHanoy_RowStack, self).cardsBuild(from_stack, cards):
            return False
        return self.cards[-1]['rank'] > cards[0]['rank']


class TowerOfHanoy(game.Game):
    __info__ = dict(id=124, name="Tower of Hanoy", game_type=GT.PUZZLE_TYPE,
                    decks=1, redeals=0, skill_level=SL.SKILL, suits=(2, ),
                    ranks=range(9), version='3.10')
    _hint_ = CautiousDefaultHint
    _talon_ = stack.InitialDealTalon
    _row_ = Wrap(TowerOfHanoy_RowStack, max_accept=1, max_move=1)

    def _create_game(self):
        l, s = Layout(self), self.s
        h = max(2 * l.YS, l.YS + (len(self.cards) - 1) * l.YOFFSET + l.YM)
        self.setSize(l.XM + 5 * l.XS, l.YM + l.YS + h)
        for x in l.row_iter(x=l.XM + l.XS, npiles=3):
            s['rows'].append(self._row_(x, l.YM, game=self))
        s['talon'] = self._talon_(l.XM, self.height - l.YS, game=self)
        l.defaultStackGroups()

    def _start(self):
        self._play_sound('deal')
        for i in range(3):
            self.s['talon'].dealRow()

    @property
    def is_complete(self):
        return any(len(s.cards) == len(self.cards) for s in self.s['rows'])

    def _autopiles(self, event=None):
        """
        Return piles for auto or quick move.

        Overide to disable autoflip, autodrop.

        .. \_autopiles(self, event=None) -> seq(seq(Pile ...), seq(Pile ...),
             seq(Pile ...))
        """
        return autostacks.quickplay(super(TowerOfHanoy, self)._autopiles(event))


class HanoiPuzzle_RowStack(TowerOfHanoy_RowStack):

    def getBottomImage(self):
        if self.id == len(self.game.s['rows']) - 1:
            return self.game.images.getBottom(mode='suit',
                                              index=self.cap['base_suit'])
        else:
            return super(HanoiPuzzle_RowStack, self).getBottomImage()


class HanoiPuzzle4(TowerOfHanoy):
    __info__ = dict(id=207, name="Hanoi Puzzle 4", game_type=GT.PUZZLE_TYPE,
                    decks=1, redeals=0, skill_level=SL.SKILL, suits=(2, ),
                    ranks=range(4), rules_filename="hanoipuzzle.html",
                    version='4.60')
    _row_ = Wrap(HanoiPuzzle_RowStack, max_accept=1, max_move=1)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return TWO on top by suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllTwos)

    def _start(self):
        self._play_sound('deal')
        for i in range(len(self.cards)):
            self.s['talon'].dealRow(rows=self.s['rows'][:1])

    @property
    def is_complete(self):
        return len(self.s['rows'][-1].cards) == len(self.cards)


class HanoiPuzzle5(HanoiPuzzle4):
    __info__ = dict(id=208, name="Hanoi Puzzle 5", game_type=GT.PUZZLE_TYPE,
                decks=1, redeals=0, skill_level=SL.SKILL, suits=(2, ),
                ranks=range(5), rules_filename="hanoipuzzle.html",
                    version='4.60')


class HanoiPuzzle6(HanoiPuzzle4):
    __info__ = dict(id=209, name="Hanoi Puzzle 6", game_type=GT.PUZZLE_TYPE,
                    decks=1, redeals=0, skill_level=SL.SKILL, suits=(2, ),
                    ranks=range(6), rules_filename="hanoipuzzle.html",
                    version='4.60')


class HanoiSequence(TowerOfHanoy):
    __info__ = dict(id=769, name="Hanoy Sequence", game_type=GT.PUZZLE_TYPE,
                    decks=1, redeals=0, skill_level=SL.SKILL, suits=(2, ),
                    ranks=range(9),
                    version='2.00fc')

    @property
    def is_complete(self):
        return (super(HanoiSequence, self).is_complete and
                any (cmp_cards.isRankSequence(s.cards) for s in self.s['rows']))

PROVIDES = [TowerOfHanoy, HanoiPuzzle4, HanoiPuzzle5, HanoiPuzzle6,
            HanoiSequence]